package com.sh.data.engine.domain.authority.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sh.data.engine.common.constants.HttpStatus;
import com.sh.data.engine.common.constants.code.BizCodes;
import com.sh.data.engine.common.enumDefinition.RoleEnum;
import com.sh.data.engine.common.exception.BusinessException;
import com.sh.data.engine.common.util.ServletUtils;
import com.sh.data.engine.domain.authority.model.domain.UserProjectDomain;
import com.sh.data.engine.domain.authority.model.param.UserProjectSaveParam;
import com.sh.data.engine.domain.authority.service.RoleService;
import com.sh.data.engine.domain.authority.service.UserProjectService;
import com.sh.data.engine.domain.base.model.PageResult;
import com.sh.data.engine.domain.base.model.UserContext;
import com.sh.data.engine.domain.base.model.enums.Database;
import com.sh.data.engine.domain.feign.FeignUser;
import com.sh.data.engine.domain.feign.FeignUserPage;
import com.sh.data.engine.domain.integration.datasource.model.param.DataSourceSaveParam;
import com.sh.data.engine.domain.integration.datasource.service.DataSourceService;
import com.sh.data.engine.domain.management.model.param.BaseQueryParam;
import com.sh.data.engine.domain.shims.DbManagerFactory;
import com.sh.data.engine.domain.shims.db.BaseDbManager;
import com.sh.data.engine.domain.shims.db.DbOptions;
import com.sh.data.engine.domain.util.ConvertUtil;
import com.sh.data.engine.domain.util.PaginateUtil;
import com.sh.data.engine.domain.workspace.index.model.domain.BaseProjectDomain;
import com.sh.data.engine.domain.workspace.index.model.domain.ProjectDomain;
import com.sh.data.engine.domain.workspace.index.model.domain.ProjectStatisticDomain;
import com.sh.data.engine.domain.workspace.index.model.mapper.*;
import com.sh.data.engine.domain.workspace.manager.model.domain.StorageDetailDomain;
import com.sh.data.engine.domain.workspace.manager.model.domain.UserDomain;
import com.sh.data.engine.domain.workspace.manager.model.domain.UserMeta;
import com.sh.data.engine.domain.workspace.manager.model.domain.UserYunQiaoDomain;
import com.sh.data.engine.domain.workspace.manager.model.mapper.StorageEntityMapper;
import com.sh.data.engine.domain.workspace.manager.model.param.ProjectSaveParam;
import com.sh.data.engine.domain.workspace.manager.model.param.StorageSaveParam;
import com.sh.data.engine.domain.workspace.manager.service.StorageService;
import com.sh.data.engine.repository.dao.authority.RoleMapper;
import com.sh.data.engine.repository.dao.authority.UserProjectMapper;
import com.sh.data.engine.repository.dao.authority.entity.UserProjectEntity;
import com.sh.data.engine.repository.dao.integration.datasource.DataSourceMapper;
import com.sh.data.engine.repository.dao.workspace.index.ProjectMapper;
import com.sh.data.engine.repository.dao.workspace.index.ProjectStatisticsMapper;
import com.sh.data.engine.repository.dao.workspace.index.entity.ProjectEntity;
import com.sh.data.engine.repository.dao.workspace.index.entity.ProjectStatisticsEntity;
import com.sh.data.engine.repository.dao.workspace.manager.StorageMapper;
import com.sh.data.engine.repository.dao.workspace.manager.entity.StorageEntity;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.SQLException;
import java.util.*;


/**
 * @author: mengzheng.mhc
 * @date: 2024/6/25 9:53
 */
@Service
public class UserProjectServiceImpl extends ServiceImpl<UserProjectMapper, UserProjectEntity> implements UserProjectService {

    @Autowired
    @Lazy
    private RoleService roleService;

    @Autowired
    private FeignUserPage feignUserPage;

    @Autowired
    private ProjectMapper projectMapper;

    @Autowired
    private StorageMapper storageMapper;

    @Autowired
    private DataSourceMapper dataSourceMapper;

    @Autowired
    private UserProjectDomainMapper userProjectDomainMapper;

    @Autowired
    private FeignUser feignUser;

    @Autowired
    private ProjectDomainMapper projectDomainMapper;

    @Autowired
    private StorageDetailDomainMapper storageDetailDomainMapper;

    @Autowired
    private ProjectEntityMapper projectEntityMapper;

    @Autowired
    private StorageEntityMapper storageEntityMapper;

    @Autowired
    private ProjectStatisticsMapper projectStatisticsMapper;

    @Autowired
    private ProjectStatisticDomainMapper projectStatisticDomainMapper;

    @Lazy
    @Autowired
    private StorageService storageService;

    @Lazy
    @Autowired
    private DataSourceService dataSourceService;

    //该id在不同的环境不一样
    @Value("${super.admin.id}")
    private String SUPER_ADMIN;

    @Override
    public List<UserProjectDomain> getUserProjectListByRoleId(Integer roleId) {
        LambdaQueryWrapper<UserProjectEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserProjectEntity::getRoleId, roleId);
        List<UserProjectEntity> user = this.baseMapper.selectList(wrapper);
        return userProjectDomainMapper.map(user);
    }

    @Override
    public PageResult<BaseProjectDomain> getProjectList(BaseQueryParam param) {
        String guid = UserContext.getUserId();
        LambdaQueryWrapper<UserProjectEntity> wrapper = new LambdaQueryWrapper<>();
        assert guid != null;
        if (!guid.equals(SUPER_ADMIN)) {
            wrapper.eq(UserProjectEntity::getUserId, guid);
        }

        // 根据String类型的guid查询userProjectEntities
        List<UserProjectEntity> userProjectEntities = this.baseMapper.selectList(wrapper);
        if (CollectionUtil.isEmpty(userProjectEntities)) {
            return null;
        }

        //获取userProjectEntities中的id
        List<Long> projectIds = userProjectEntities.stream().map(UserProjectEntity::getProjectId).toList();
        LambdaQueryWrapper<ProjectEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(ProjectEntity::getId, projectIds);
        lambdaQueryWrapper.orderByAsc(ProjectEntity::getId);
        Page<ProjectEntity> projectEntities = projectMapper.selectPage(new Page<>(param.getPageNum(), param.getPageSize()), lambdaQueryWrapper);

        PageResult<ProjectEntity> projectPageResult = PageResult.convert(projectEntities);

        return ConvertUtil.convertPageInfo(projectPageResult, BaseProjectDomain.class);
    }

    private Integer getRoleIdByUserId(String userId) {
        return this.baseMapper.selectList(new LambdaQueryWrapper<UserProjectEntity>()
                        .eq(UserProjectEntity::getProjectId, ServletUtils.getProjectId())
                        .eq(UserProjectEntity::getUserId, userId))
                .stream()
                .map(UserProjectEntity::getRoleId).findFirst().orElse(null);//目前一个用户只能拥有一个角色，list中只有一个元素
    }

    private Integer getRoleIdByProjectId(Long projectId) {
        return this.baseMapper.selectList(new LambdaQueryWrapper<UserProjectEntity>()
                        .eq(UserProjectEntity::getProjectId, projectId)
                        .eq(UserProjectEntity::getUserId, UserContext.getUserId()))
                .stream()
                .map(UserProjectEntity::getRoleId).findFirst().orElse(null);
    }

    /**
     * 获取当前登录用户的空间列表(分页),super_admin获取所有
     */
    @Override
    public PageResult<ProjectStatisticDomain> getEnrichedProjectList(BaseQueryParam param) {
        String guid = UserContext.getUserId();
        LambdaQueryWrapper<UserProjectEntity> wrapper = new LambdaQueryWrapper<>();
        assert guid != null;
        if (!guid.equals(SUPER_ADMIN)) {
            wrapper.eq(UserProjectEntity::getUserId, guid);
        }
        //根据String类型的guid查询userProjectEntities
        List<UserProjectEntity> userProjectEntities = this.baseMapper.selectList(wrapper);
        if (userProjectEntities != null && !userProjectEntities.isEmpty()) {
            //获取userProjectEntities中的id
            List<Long> projectIds = userProjectEntities.stream().map(UserProjectEntity::getProjectId).toList();
            LambdaQueryWrapper<ProjectEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.in(ProjectEntity::getId, projectIds);
            lambdaQueryWrapper.orderByAsc(ProjectEntity::getId);
            Page<ProjectEntity> projectEntities = projectMapper.selectPage(new Page<>(param.getPageNum(), param.getPageSize()), lambdaQueryWrapper);

            LambdaQueryWrapper<ProjectStatisticsEntity> wrapperStatistics = new LambdaQueryWrapper<>();
            wrapperStatistics.in(ProjectStatisticsEntity::getProjectId, projectIds);
            wrapperStatistics.orderByAsc(ProjectStatisticsEntity::getProjectId);
            IPage<ProjectStatisticsEntity> projectStatisticsEntityIPage = projectStatisticsMapper.selectPage(new Page<>(param.getPageNum(), param.getPageSize()), wrapperStatistics);

            PageResult<ProjectStatisticsEntity> projectPageResult = PageResult.convert(projectStatisticsEntityIPage);
            PageResult<ProjectStatisticDomain> projectStatisticDomainPageResult = ConvertUtil.convertPageInfo(projectPageResult, ProjectStatisticDomain.class);

            for (int i = 0; i < projectEntities.getRecords().size(); i++) {
                ProjectStatisticDomain projectStatisticDomain = projectStatisticDomainPageResult.getResult().get(i);
                projectStatisticDomain.setId(projectStatisticDomain.getProjectId());
                projectStatisticDomain.setProjectName(projectEntities.getRecords().get(i).getName());
                projectStatisticDomain.setDescription(projectEntities.getRecords().get(i).getDescription());
                projectStatisticDomain.setCreateTime(projectEntities.getRecords().get(i).getCreateTime());
            }
            return projectStatisticDomainPageResult;
        } else {
            return null;
        }
    }


    /**
     * 获取当前登录用户的空间列表(不分页)，super_admin获取所有
     */
    @Override
    public List<ProjectStatisticDomain> getProjectPrivilege() {
        String guid = UserContext.getUserId();
        LambdaQueryWrapper<UserProjectEntity> wrapper = new LambdaQueryWrapper<>();
        assert guid != null;
        if (!guid.equals(SUPER_ADMIN)) {
            wrapper.eq(UserProjectEntity::getUserId, guid);
        }
        //根据guid查询userProjectEntities
        List<UserProjectEntity> userProjectEntities = this.baseMapper.selectList(wrapper);
        if (userProjectEntities != null && !userProjectEntities.isEmpty()) {
            //获取userProjectEntities中的id
            List<Long> projectIds = userProjectEntities
                    .stream()
                    .map(UserProjectEntity::getProjectId)
                    .toList();
            //查询空间实体
            LambdaQueryWrapper<ProjectEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.in(ProjectEntity::getId, projectIds);
            List<ProjectEntity> projectEntities = projectMapper.selectList(lambdaQueryWrapper);

            //查询空间统计实体
            LambdaQueryWrapper<ProjectStatisticsEntity> wrapperSta = new LambdaQueryWrapper<>();
            wrapperSta.in(ProjectStatisticsEntity::getProjectId, projectIds);
            List<ProjectStatisticsEntity> result = projectStatisticsMapper.selectList(wrapperSta);
            //领域对象拼接
            List<ProjectStatisticDomain> list = result.stream().map(projectStatisticDomainMapper::map).toList();
            for (int i = 0; i < list.size(); i++) {
                list.get(i).setProjectName(projectEntities.get(i).getName());
                list.get(i).setDescription(projectEntities.get(i).getDescription());
                list.get(i).setCreateTime(projectEntities.get(i).getCreateTime());
            }
            return list;
        } else
            return null;
    }

    @Override
    public StorageDetailDomain getStorageInfo(Long projectId) {
        LambdaQueryWrapper<ProjectEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProjectEntity::getId, projectId);
        List<ProjectEntity> projectEntities = projectMapper.selectList(wrapper);
        if (projectEntities != null && !projectEntities.isEmpty()) {
            ProjectEntity projectEntity = projectEntities.get(0);
            LambdaQueryWrapper<StorageEntity> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(StorageEntity::getId, projectEntity.getStorageId());
            List<StorageEntity> storageEntities = storageMapper.selectList(wrapper1);
            if (storageEntities != null && !storageEntities.isEmpty()) {
                StorageEntity storageEntity = storageEntities.get(0);
                return storageDetailDomainMapper.map(storageEntity);
            }
        }
        return null;
    }


    @Override
    @Transactional
    public String addProject(UserProjectSaveParam param) {//创建空间会往4张表插入5条记录
        String guid = UserContext.getUserId();
        ProjectSaveParam projectSaveParam = param.getProject();
        StorageSaveParam storageSaveParam = param.getStorage();
        if (storageSaveParam.getStorageName() == null) {
            // 默认在不指定存储资源名称时，使用工作空间名称作为存储资源名称
            storageSaveParam.setStorageName(projectSaveParam.getName());
        }

        // 确保存储资源名称不存在
        ensureStorageNameNotExists(storageSaveParam);

        // 确保工作空间名称不存在
        ensureProjectNameNotExists(projectSaveParam);

        // 获取数据库版本
        String dbVersion = getDatabaseVersion(storageSaveParam);
        StorageEntity.Rmdbs rmdbs = buildRmdbs(storageSaveParam, dbVersion);

        //插入存储记录
        StorageEntity storageEntity = storageEntityMapper.saveParamToEntity(storageSaveParam);
        storageEntity.setStatus(dbVersion == null ? 0 : 1);
        storageEntity.setRmdbs(rmdbs);
        storageEntity.setRmdbsInfo();
        storageEntity.setStatusUpdateTime(new Date());
        storageMapper.insert(storageEntity);

        //插入成功之后会自动生成对应的id，获取storageId
        StorageEntity insertedStorageEntity = storageMapper.selectOne(
                new LambdaQueryWrapper<StorageEntity>()
                        .eq(StorageEntity::getStorageName, storageEntity.getStorageName())
                        .eq(StorageEntity::getRowState, 1));

        // 插入工作空间记录
        ProjectEntity projectEntity = projectEntityMapper.saveParamToEntity(projectSaveParam);
        projectEntity.setStorageId(insertedStorageEntity.getId());
        projectMapper.insert(projectEntity);

        // 插入成功之后会自动生成对应的id，获取projectId
        ProjectEntity insertedProjectEntity = projectMapper.selectOne(
                new LambdaQueryWrapper<ProjectEntity>()
                        .eq(ProjectEntity::getName, projectEntity.getName())
                        .eq(ProjectEntity::getRowState, 1));

        // 插入数据源
        StorageDetailDomain detailStorage = storageService.getDetailStorage(insertedStorageEntity.getId(), false);
        DataSourceSaveParam dataSourceSaveParam = detailStorage.convertToDataSourceSaveParam();
        dataSourceSaveParam.setProjectId(insertedProjectEntity.getId());
        dataSourceService.saveDataSource(dataSourceSaveParam);

        //插入用户项目关联记录
        this.baseMapper.insert(UserProjectEntity.builder()
                .projectId(insertedProjectEntity.getId())
                .userId(guid)
                .roleId(RoleEnum.PROJECT_OWNER.getStatus())
                .build());
        if (!Objects.equals(guid, SUPER_ADMIN)) {
            this.baseMapper.insert(UserProjectEntity.builder()
                    .projectId(insertedProjectEntity.getId())
                    .userId(SUPER_ADMIN)
                    .roleId(RoleEnum.SUPER_ADMIN.getStatus())
                    .build());
        }
        //插入空间统计记录
        projectStatisticsMapper.insert(
                ProjectStatisticsEntity.builder().projectId(insertedProjectEntity.getId()).userNum(1L).registerDsNum(1L).build());
        return "create projectEntity success";
    }

    @Override
    public ProjectDomain getProject(Long projectId) {
        Integer roleId = getRoleIdByProjectId(projectId);
        if (roleId == null) {
            throw new BusinessException(BizCodes.NO_MATCHING_RECORD_ERROR, HttpStatus.BAD_REQUEST);
        }

        LambdaQueryWrapper<ProjectEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProjectEntity::getId, projectId);
        ProjectEntity projectEntity = projectMapper.selectOne(wrapper);
        if (projectEntity == null) {
            throw new BusinessException(BizCodes.NO_MATCHING_RECORD_ERROR, HttpStatus.BAD_REQUEST);
        }

        ProjectDomain projectDomain = projectDomainMapper.map(projectEntity);

        LambdaQueryWrapper<StorageEntity> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(StorageEntity::getId, projectEntity.getStorageId());
        StorageEntity storageEntity = storageMapper.selectOne(wrapper1);
        StorageDetailDomain storageDetailDomain = storageDetailDomainMapper.map(storageEntity);
        projectDomain.setStorageDetailDomain(storageDetailDomain);

        return projectDomain;
    }

    @Override
    @Transactional
    public String deleteProject(Long projectId) {
        // 判断当前用户是否是空间owner或者super_admin
        ProjectEntity projectEntity = projectMapper.selectById(projectId);
        LambdaQueryWrapper<UserProjectEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserProjectEntity::getProjectId, projectId);
        if (this.baseMapper.selectList(wrapper).size() == 2) {
            //删除用户空间关系记录
            this.baseMapper.deleteByMap(Map.of("project_id", projectId));
            //删除数据源
            dataSourceMapper.deleteByMap(Map.of("project_id", projectId));
            //删除存储记录
            storageMapper.deleteById(projectEntity.getStorageId());
            //删除空间记录
            projectMapper.deleteById(projectId);
            //删除空间统计记录
            projectStatisticsMapper.deleteById(projectStatisticsMapper.selectOne(new LambdaQueryWrapper<ProjectStatisticsEntity>().eq(ProjectStatisticsEntity::getProjectId, projectId)).getId());
            return projectEntity.getName() + " delete project success";
        } else if (!Objects.equals(getRoleIdByProjectId(projectId), RoleEnum.SUPER_ADMIN.getStatus()) && !Objects.equals(getRoleIdByProjectId(projectId), RoleEnum.PROJECT_OWNER.getStatus()) && !Objects.equals(getRoleIdByProjectId(projectId), RoleEnum.PROJECT_ADMIN.getStatus())) {
            throw new BusinessException("privilege not support");
        } else {
            //删除用户空间关系记录
            this.baseMapper.deleteByMap(Map.of("project_id", projectId));
            //删除数据源
            dataSourceMapper.deleteByMap(Map.of("project_id", projectId));
            //删除存储记录
            storageMapper.deleteById(projectEntity.getStorageId());
            //删除空间记录
            projectMapper.deleteById(projectId);
            //删除空间统计记录
            projectStatisticsMapper.deleteById(projectStatisticsMapper.selectOne(new LambdaQueryWrapper<ProjectStatisticsEntity>().eq(ProjectStatisticsEntity::getProjectId, projectId)).getId());
            return projectEntity.getName() + " delete project success";
        }
    }

    /**
     * 根据账号名提取id
     */
    public String getUserIdByUserName(String userName) {
        JSONObject map = feignUserPage.getMap(1, 9999, "userName eq " + userName);
        List<UserDomain> resources = (List<UserDomain>) map.get("resources");
        for (int i = 0; i < resources.size(); i++) {
            // 将list中的数据转成json字符串
            String jsonObject = JSON.toJSONString(resources.get(i));
            //将json转成需要的对象
            UserDomain user = JSONObject.parseObject(jsonObject, UserDomain.class);
            if (user.getUserName().equals(userName)) {
                return user.getId();
            }
        }
        throw new BusinessException("username not exists");
    }

    private boolean isValidRoleId(int roleId) {
        return roleId != RoleEnum.SUPER_ADMIN.getStatus() && roleId != RoleEnum.PROJECT_OWNER.getStatus();
    }

    /**
     * 添加成员不能添加0和1
     *
     * @param roleId
     * @param userName
     * @return
     */
    @Override
    @Transactional
    public int addProjectUser(int roleId, String userName) {
        // 验证roleId是否有效
        if (!isValidRoleId(roleId)) {
            // 返回错误响应
            throw new BusinessException("roleId can not be 1(super admin) or 2(project owner)");
        }
        String userId = this.getUserIdByUserName(userName);
        //判断当前用户是否具备添加用户的权限
//        if (Objects.equals(UserContext.getUserId(), SUPER_ADMIN)
//                || Objects.equals(getRoleIdCurrent(), RoleEnum.PROJECT_OWNER.getStatus())
//                || Objects.equals(getRoleIdCurrent(), RoleEnum.PROJECT_ADMIN.getStatus())) {
        //判断该成员是否已经具备该角色
        if (!this.baseMapper.selectList(new LambdaQueryWrapper<UserProjectEntity>().eq(UserProjectEntity::getProjectId, ServletUtils.getProjectId()).eq(UserProjectEntity::getUserId, userId).eq(UserProjectEntity::getRoleId, roleId)).isEmpty()) {
            throw new BusinessException("privilege has already exist");
        } else if (this.baseMapper.selectList(new LambdaQueryWrapper<UserProjectEntity>().eq(UserProjectEntity::getProjectId, ServletUtils.getProjectId()).eq(UserProjectEntity::getUserId, userId)).isEmpty()) {
            this.baseMapper.insert(UserProjectEntity.builder()
                    .projectId(ServletUtils.getProjectId())
                    .userId(userId)
                    .roleId(roleId)
                    .build());
            return 1;
        } else {
            this.baseMapper.update(UserProjectEntity.builder().roleId(roleId).build(), new LambdaQueryWrapper<UserProjectEntity>().eq(UserProjectEntity::getProjectId, ServletUtils.getProjectId()).eq(UserProjectEntity::getUserId, userId));
            return 1;
        }
//        } else {
//            throw new BusinessException("privilege not support");
//        }
    }

    /**
     * 页面已经展示了空间成员，显示根据用户id，删除该用户
     * 移除成员的角色如果是1L或者0L，则不能删除
     *
     * @param userName
     * @return
     */
    @Override
    @Transactional
    public int deleteProjectUser(String userName) {
        String userId = this.getUserIdByUserName(userName);
        //判断当前用户是否具备删除用户的权限
//        if (Objects.equals(UserContext.getUserId(), SUPER_ADMIN)
//                || Objects.equals(getRoleIdCurrent(), RoleEnum.PROJECT_OWNER.getStatus())
//                || Objects.equals(getRoleIdCurrent(), RoleEnum.PROJECT_ADMIN.getStatus())) {
        LambdaQueryWrapper<UserProjectEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserProjectEntity::getProjectId, ServletUtils.getProjectId()).eq(UserProjectEntity::getUserId, userId);
        // 验证roleId是否有效
        if (!isValidRoleId(this.baseMapper.selectList(wrapper).get(0).getRoleId())) {
            throw new BusinessException("project owner or super admin can not be delete");
        } else if (this.baseMapper.delete(wrapper) > 0) {
            return 1;
        } else return 0;
//        } else {
//            throw new BusinessException("privilege not support");
//        }
    }

    /**
     * 页面已经展示了空间成员，显示根据用户名，更新该用户角色
     *
     * @param userName
     * @param roleId
     * @return
     */
    @Override
    @Transactional
    public int updateProjectUser(String userName, int roleId) {
        // 验证roleId是否有效
        if (!isValidRoleId(roleId)) {
            throw new BusinessException("roleId can not be 1(super admin) or 2(project owner)");
        }
        String userId = this.getUserIdByUserName(userName);
        //判断当前用户是否具备编辑用户的权限
        LambdaQueryWrapper<UserProjectEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserProjectEntity::getProjectId, ServletUtils.getProjectId()).eq(UserProjectEntity::getUserId, userId);
        if (this.baseMapper.update(UserProjectEntity.builder().roleId(roleId).build(), wrapper) > 0) {
            return 1;
        } else return 0;
    }

    /**
     * super_admin project_owner project_admin
     *
     * @return
     */
    @Override
    public PageResult<UserDomain> getProjectUser(Integer pageNum, Integer pageSize) {
        LambdaQueryWrapper<UserProjectEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserProjectEntity::getProjectId, ServletUtils.getProjectId());
        List<UserProjectEntity> userProjectEntities = this.baseMapper.selectList(wrapper);
        List<String> userIdlist = userProjectEntities.stream().map(UserProjectEntity::getUserId).toList();
        //用逗号拼接ids
        String idsStr = String.join(",", userIdlist);
        //批查询云巧用户
        JSONObject mapResult = feignUserPage.getMap(1, 99999, "externalIds eq " + idsStr);
        Object totalResultsObj = mapResult.get("totalResults");
        Long totalResults;
        if (totalResultsObj instanceof Integer) {
            totalResults = ((Integer) totalResultsObj).longValue();
        } else if (totalResultsObj instanceof Long) {
            totalResults = (Long) totalResultsObj;
        } else {
            throw new IllegalArgumentException("totalResults must be an Integer or Long");
        }
        Integer startIndex = (Integer) mapResult.get("startIndex");
        Integer itemsPerPage = (Integer) mapResult.get("itemsPerPage");
        Integer totalPages = Math.toIntExact(totalResults / itemsPerPage) + 1;

        PageResult<UserDomain> resultPage = new PageResult<>();
        List<UserDomain> result = new ArrayList<>();
        for (int i = 0; i < userIdlist.size(); i++) {

            UserYunQiaoDomain yunQiaoUser = feignUser.getMap(userIdlist.get(i));
            if (yunQiaoUser != null && yunQiaoUser.getId() != null) {
                result.add(this.convertYunqiaoUser(yunQiaoUser));
            }
        }
        result = result.stream().distinct().toList();
        resultPage.setTotalPages(totalPages);
        //对result去重，空间拥有者可能是超级管理员，保留一条记录即可
        resultPage.setResult(PaginateUtil.paginate(result, pageNum, pageSize));
        resultPage.setTotalElements(totalResults);
        resultPage.setPageNum(startIndex);
        resultPage.setPageSize(pageSize);
        return resultPage;
    }

    private UserDomain convertYunqiaoUser(UserYunQiaoDomain user) {
        UserDomain userDomain = new UserDomain();
        userDomain.setUserName(user.getUserName());
        userDomain.setId(user.getId());
        //如果列表为空，则值为null
        if (CollectionUtils.isNotEmpty(user.getEmails())) {
            userDomain.setEmail(user.getEmails().get(0).get("value"));
        }
        if (CollectionUtils.isNotEmpty(user.getPhoneNumbers())) {
            userDomain.setPhoneNumber(user.getPhoneNumbers().get(0).get("value"));
        }
        userDomain.setDisplayName(user.getDisplayName());
        userDomain.setDeleted(user.isDeleted());
        userDomain.setActive(user.isActive());
        userDomain.setGroups(user.getGroups());
        UserMeta userMeta = new UserMeta(user.getMeta().getCreated(), user.getMeta().getLastModified(), user.getMeta().getResourceType());
        userDomain.setCreated(userMeta.getCreated());
        userDomain.setLastModified(userMeta.getLastModified());
        //查看空间内部成员需要成员角色信息
        userDomain.setRoleId(getRoleIdByUserId(user.getId()));
        //根据roleId获取roleName
        userDomain.setRoleName(roleService.getRoleNameByRoleId(getRoleIdByUserId(user.getId())));
        //判断是否是超级管理员
        userDomain.setIsAuth(user.getId().equals(SUPER_ADMIN) ? 1 : 0);
        return userDomain;
    }

    /**
     * description 判断存储源名称是否重复
     *
     * @author : mingxi.xpb
     * @date : 2022/1/12 15:17
     */
    private void ensureStorageNameNotExists(StorageSaveParam param) {
        LambdaQueryWrapper<StorageEntity> lambdaQueryWrapper =
                new LambdaQueryWrapper<StorageEntity>()
                        .eq(
                                StringUtils.isNotBlank(param.getStorageName()),
                                StorageEntity::getStorageName,
                                param.getStorageName())
                        .ne(Objects.nonNull(param.getStorageId()), StorageEntity::getId, param.getStorageId());

        List<StorageEntity> storageEntities = storageMapper.selectList(lambdaQueryWrapper);
        if (CollectionUtils.isNotEmpty(storageEntities)) {
            throw new BusinessException(BizCodes.STORAGE_NAME_ALREADY_EXISTS_ERROR, HttpStatus.BAD_REQUEST);
        }
    }

    private void ensureProjectNameNotExists(ProjectSaveParam param) {
        LambdaQueryWrapper<ProjectEntity> lambdaQueryWrapper =
                new LambdaQueryWrapper<ProjectEntity>()
                        .eq(
                                StringUtils.isNotBlank(param.getName()),
                                ProjectEntity::getName,
                                param.getName())
                        .ne(Objects.nonNull(param.getId()), ProjectEntity::getId, param.getId());

        List<ProjectEntity> projectEntities = projectMapper.selectList(lambdaQueryWrapper);
        if (CollectionUtils.isNotEmpty(projectEntities)) {
            throw new BusinessException(BizCodes.PROJECT_NAME_ALREADY_EXISTS_ERROR, HttpStatus.BAD_REQUEST);
        }
    }

    private StorageEntity.Rmdbs buildRmdbs(StorageSaveParam param, String dbVersion) {
        String storageType = param.getStorageType();
        if (storageType.equals("SAP")) {
            param.setSchema(param.getDbName());
        }
        return StorageEntity.Rmdbs.builder()
                .username(param.getUsername())
                .password(param.getPassword())
                .version(dbVersion)
                .server(param.getServer())
                .port(param.getPort())
                .dbName(param.getDbName())
                .hiveSiteXmlPath(param.getHiveSiteAddress())
                .originalFilename(param.getOriginalFilename())
                .schema(param.getSchema())
                .connectionProperty(param.getConnectionProperty())
                .build();
    }

    private String getDatabaseVersion(StorageSaveParam param) {
        String dbVersion = null;
        BaseDbManager dbManager = getDbManager(
                param.getStorageType(),
                param.getUsername(),
                param.getPassword(),
                param.getStorageLink(),
                param.getHiveSiteAddress());
        if (dbManager == null) {
            return dbVersion;
        }

        try {
            dbVersion = dbManager.getDbVersion();
            dbManager.testConnection();
            ;
        } catch (SQLException e) {
            dbVersion = null;
            log.error(e.getMessage());
        }

        return dbVersion;
    }

    private BaseDbManager getDbManager(
            String storageType,
            String username,
            String password,
            String storageLink,
            String hiveSiteXmlPath) {
        Database database = Database.from(storageType);
        DbOptions dbOptions = new DbOptions(database, username, password, storageLink, hiveSiteXmlPath);
        try {
            return DbManagerFactory.getDbManager(database, dbOptions);
        } catch (Exception e) {
            log.error("failed to create DbManager, please check your link information!");
            return null;
        }
    }
}
